using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Drawing;
using System.Data;
using System.Collections;
using System.Windows.Forms;
using GuavaData;
using System.Globalization;
using System.Threading;

namespace GuavaLib
{
    public partial class GDateTimePicker : DateTimePicker,Guava
    {
        // true, when no date shall be displayed (empty DateTimePicker)
        private bool _isNull;

        // If _isNull = true, this value is shown in the DTP
        private string _nullValue;

        // The format of the DateTimePicker control
        private DateTimePickerFormat _format = DateTimePickerFormat.Long;

        // The custom format of the DateTimePicker control
        private string _customFormat;

        // The format of the DateTimePicker control as string
        private string _formatAsString;

        public new String CustomFormat
        {
            get { return _customFormat; }
            set
            {
                _customFormat = value;
            }
        }

        public new DateTimePickerFormat Format
        {
            get { return _format; }
            set
            {
                _format = value;
                SetFormat();
                OnFormatChanged(EventArgs.Empty);
            }
        }

        private void SetFormat()
        {
            CultureInfo ci = Thread.CurrentThread.CurrentCulture;
            DateTimeFormatInfo dtf = ci.DateTimeFormat;
            switch (_format)
            {
                case DateTimePickerFormat.Long:
                    FormatAsString = dtf.LongDatePattern;
                    break;
                case DateTimePickerFormat.Short:
                    FormatAsString = dtf.ShortDatePattern;
                    break;
                case DateTimePickerFormat.Time:
                    FormatAsString = dtf.ShortTimePattern;
                    break;
                case DateTimePickerFormat.Custom:
                    FormatAsString = this.CustomFormat;
                    break;
            }
        }

        private string FormatAsString
        {
            get { return _formatAsString; }
            set
            {
                _formatAsString = value;
                base.CustomFormat = value;
            }
        }

        public new object Value
        {
            get
            {
                if (_isNull)
                    return null;
                else
                    return base.Value;
            }
            set
            {
                if (value == null || value == DBNull.Value)
                {
                    SetToNullValue();
                }
                else if ((value is string) && ((string)value == this._nullValue))
                {
                    SetToNullValue();
                }
                else
                {
                    SetToDateTimeValue();
                    base.Value = (DateTime)value;
                }
            }
        }

        private void SetToDateTimeValue()
        {
            if (_isNull)
            {
                SetFormat();
                _isNull = false;
                base.OnValueChanged(new EventArgs());
            }
        }

        private void SetToNullValue()
        {
            _isNull = true;
            base.CustomFormat = (_nullValue == null || _nullValue == String.Empty)
                                ? " " : "'" + NullValue + "'";
        }

        public string NullValue
        {
            get { return _nullValue; }
            set { _nullValue = value; }
        }

        protected override void OnCloseUp(EventArgs e)
        {
            if (Control.MouseButtons == MouseButtons.None && _isNull)
            {
                SetToDateTimeValue();
                _isNull = false;
            }
            base.OnCloseUp(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                this.Value = NullValue;
                OnValueChanged(EventArgs.Empty);
            }
            base.OnKeyUp(e);
        }







        
        
        
        string gname;
        System.Windows.Forms.Label lab;
#if (SPARCE)
        private ContextMenu popUpMenu;
        private MenuItem markItem;
#endif
        public GDateTimePicker() : base()
        {
            InitializeComponent();
#if (SPARCE)
            this.markItem = new MenuItem("Mark", new EventHandler(markSelection));
            CreateMenu();
            this.ContextMenu = popUpMenu;
#endif
            base.Format = DateTimePickerFormat.Custom;
            NullValue = " ";
            this.Format = DateTimePickerFormat.Long;
        }

        public System.Windows.Forms.Label Label
        {
            get { return lab; }
            set { lab = value; }
        }

#if (SPARCE)
        public void CreateMenu()
        {
            popUpMenu = new ContextMenu();
            popUpMenu.MenuItems.Add(markItem);
            // checkQueryMethod = new MenuItem("Query Method", new EventHandler(popup));
            // popUpMenu.MenuItems.Add(checkReturn);
            // popUpMenu.MenuItems.Add(checkQueryMethod);
            // checkQueryMethod.MenuItems.AddRange(regEx);
        }

        private void markSelection(object sender, EventArgs e)
        {
            // Verify that 'mark' was selected
            MenuItem miClicked = sender as MenuItem;
            if (miClicked.Text != "Mark") throw new Exception("Did not understand menu selection " + miClicked.Text);

            // Grab the current GSeed
            Control p = this;
            Control q = p.Parent;
            List<string> ls = new List<string>();
            ls.Add(this.GName);

            // Follow parents up the chain to the root form
            while (!(q is GuavaForm))
            {
                if (!(q is Guava))
                {
                    Guava r = q.Parent as Guava;
                    if (r == null) throw new Exception("Found two non-guava objects nested together in the same tree for marking.");
                    bool bfound = false;
                    foreach (Guava g in r.GComponents)
                    {
                        if (g.GComponents.Contains(p as Guava))
                        {
                            ls.Insert(0, g.GName);
                            bfound = true;
                            break;
                        }
                    }
                    if (!bfound) throw new Exception("Could not match a guava object for creating a seed for marking.");
                }
                else ls.Insert(0, (q as Guava).GName);
                p = p.Parent;
                q = q.Parent;
            }

            // Grab current seed and seed frame
            GSeed gs = (q as GuavaForm).GS;
            GSeedFrame gsf = gs.Peek();
            gsf.controls = ls;

            // Send mark to SPARCE
            SPARCEClipboard.ClipboardClass cc = new SPARCEClipboard.ClipboardClass();
            cc.CopyFodder("GuavaLauncher.GuavaLauncher", "Guava", "GuavaForms", gs.root,
                AppData.assemblyPath, "GuavaSeed", gs.ToString(), gs.formPath + ":" + this.GText,
                this.Text, Environment.MachineName,
                Environment.UserName, DateTime.Now.ToString(), false);
        }
#endif
        #region Guava Members

        [Browsable(false)]
        public LaunchType LType
        {
            get
            {
                return LaunchType.NA;
            }
        }

        [Browsable(false)]
        public ControlType CType
        {
            get
            {
                return ControlType.Attribute;
            }
        }

        [Browsable(false)]
        public string GText
        {
            get
            {
                if (this.lab == null) return null;
                return this.lab.Name;
            }
        }

        public string GName
        {
            get
            {
                if (gname == null) return this.Name;
                return gname;
            }
            set
            {
                gname = value;
            }
        }

        [Browsable(false)]
        public Point GLocation
        {
            get { return this.Location; }
        }

        [Browsable(false)]
        public Size GSize
        {
            get { return this.Size; }
        }

        [Browsable(false)]
        public List<Guava> GComponents
        {
            get { return new List<Guava>(); }
        }

        public void GBind(string table, int i)
        {
            this.DataBindings.Clear();
            Binding b = new Binding("Value", AppData.ds.Tables[table], this.GName);
            this.DataBindings.Add(b);
        }

        [Browsable(false)]
        public string GDefault
        {
            get { return this.Text; }
        }

        [Browsable(false)]
        public string GToolTip
        {
            get
            {
                Control p = this.TopLevelControl;
                if (!(p is Guava)) return null;
                ToolTip t = (p as GuavaForm).GToolTipProvider;
                if (t == null) return null;

                // Fetch the tooltip and return it
                return t.GetToolTip(this);
            }
        }

        [Browsable(false)]
        public GuavaData.Domain.Domain GDomain
        {
            get
            {
                return new GuavaData.Domain.DateTime();
            }
        }

        public Guava this[string s]
        {
            get
            {
                foreach (Guava g in this.GComponents) if (g.GName == s) return g;
                return null;
            }
        }
        #endregion

    }
}
